package com.coin900.coin.server.coin.ctrl;

import com.coin900.coin.base.CoinConstants;
import com.coin900.coin.base.FuConstants;
import com.coin900.coin.base.utils.CoinUserWalletUtils;
import com.coin900.coin.base.utils.NumberArithmeticUtils;
import com.coin900.coin.persist.coin.CoinTokenCoinVO;
import com.coin900.coin.persist.coin.CoinUserProjectVO;
import com.coin900.coin.persist.fu.*;
import com.coin900.coin.service.coin.ICoinProjectService;
import com.coin900.coin.service.coin.ICoinTokenCoinService;
import com.coin900.coin.service.coin.IFuUserShareRecordService;
import com.coin900.coin.service.fu.*;
import com.value.exception.BusinessException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import sun.misc.BASE64Encoder;

import javax.crypto.*;
import javax.crypto.spec.DESKeySpec;
import javax.servlet.http.HttpServletRequest;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 用户中心
 *
 * @author shui
 * @create 2018-01-19
 **/
@Controller
public class CoinUserCenterCtrl extends CoinController {


    /**
     * 用户中心-资产管理
     * - 提现额度 (每日提现额度要不要设置？)
     * - 用户钱包
     *
     * @param request
     * @return
     */
    @RequestMapping(value = "/capital-manage", method = RequestMethod.GET)
    public ModelAndView assets(@RequestParam(required = false) String viewType,
                               HttpServletRequest request) {

        if (CoinConstants.COIN_PAGE.equals(viewType)) {
            FuUserVO user = super.getUser();
            Long userId = user.getId();

            ModelAndView modelAndView = buildView(request, "project/capital-manage");
            FuUserVO dbUser = this.userService.getUser(userId);
            if (dbUser == null) {
                throw new BusinessException("用户不存在或未激活");
            }
            Integer idcardStatus = dbUser.getIdcardStatus();
            if (idcardStatus.equals(1)) {
                modelAndView.addObject("idcardStatus", idcardStatus);
            }

            Map<String, Object> params = new HashMap<>();
            params.put("userId", userId);
            // 只查询在钱包中显示的
            params.put("showInWalletStatus", 1);
            List<FuUserWalletVO> fuUserWalletVOS = this.walletService.loadTotalWallet(params);
            if (!fuUserWalletVOS.isEmpty()) {
                Double totalValuation = this.assetValuation(fuUserWalletVOS);
                modelAndView.addObject("walletList", fuUserWalletVOS);
                modelAndView.addObject("totalValuation", totalValuation);
                return modelAndView;
            }
        }

        return null;
    }

    /**
     * 跳转用户安全中心
     *
     * @param viewType
     * @param request
     * @return
     */
    @RequestMapping(value = "/security-center", method = RequestMethod.GET)
    public ModelAndView securityCenter(@RequestParam String viewType,
                                       HttpServletRequest request) {
        if (CoinConstants.COIN_PAGE.equals(viewType)) {
            FuUserVO user = super.getUser();
            Long userId = user.getId();

            FuUserVO dbUser = this.userService.getUser(userId);
            if (dbUser == null) {
                throw new BusinessException("用户不存在或未激活");
            }
            ModelAndView modelAndView = buildView(request, "project/security-center");
            modelAndView.addObject("model", dbUser);
            return modelAndView;
        }
        return null;
    }

    /**
     * 账号中心-会员首页
     *
     * @param request
     * @return
     */
    @RequestMapping(value = "/account-center", method = RequestMethod.GET)
    public ModelAndView stat(HttpServletRequest request) {

        FuUserVO user = super.getUser();
        Long userId = user.getId();

        // 用户信息
        FuUserVO dbUser = this.userService.getUser(userId);
        ModelAndView modelAndView = super.buildView(request, "project/account-center");
        modelAndView.addObject("userInfo", dbUser);

        // 充值记录
        Map<String, Object> params = new HashMap<>();
        params.put("userId", userId);
        params.put("dataStatus", 1);
        params.put("limit", 10);
        List<FuCapitalRechargeVO> capitalRechargeList = this.rechargeService.loadFuCapitalRecharge(params);
        if (!capitalRechargeList.isEmpty()) {
            modelAndView.addObject("capitalRechargeList", capitalRechargeList);
        }

        // 提现记录的信息
        List<FuCapitalWithdrawVO> fuCapitalWithdrawVOS = this.withdrawService.loadFuCapitalWithdraw(params);
        if (!fuCapitalWithdrawVOS.isEmpty()) {
            modelAndView.addObject("capitalWithdrawList", fuCapitalWithdrawVOS);
        }

        // 购买了的项目信息
        params.clear();
        params.put("userId", userId);
        params.put("dataStatus", 1);
        params.put("limit", 3);
        params.put("orderStatus", CoinConstants.COIN_ORDER_STATUS_PAID);
        List<CoinUserProjectVO> coinUserProjectList = this.projectService.loadUserProject(params);
        if (!coinUserProjectList.isEmpty()) {
            for (CoinUserProjectVO coinUserProjectVO : coinUserProjectList) {
                // 计算剩余天数
                Date closeTime = coinUserProjectVO.getCloseTime();
                Date now = new Date();
                long remain = closeTime.getTime() - now.getTime() > 0 ? (closeTime.getTime() - now.getTime()) : 0;
                long days = remain / (1000 * 60 * 60 * 24);
                coinUserProjectVO.setRemainDay(String.valueOf(days));
            }
            modelAndView.addObject("coinUserProjectList", coinUserProjectList);
        }

        params.clear();
        params.put("userId", userId);
        params.put("dataStatus", 1);
        // 只查询在钱包中显示的
        params.put("showInWalletStatus", 1);
        List<FuUserWalletVO> fuUserWalletVOS = this.walletService.loadFuUserWallet(params);
        if (!fuUserWalletVOS.isEmpty()) {
            Double totalValuation = this.assetValuation(fuUserWalletVOS);
            modelAndView.addObject("totalValuation", totalValuation);
        } else {
            modelAndView.addObject("totalValuation", 0);
        }

        return modelAndView;
    }

    /**
     * 显示邀请的用户
     *
     * @param viewType
     * @param request
     * @return
     */
    @RequestMapping(value = "/invited", method = RequestMethod.GET)
    public ModelAndView invited(@RequestParam(required = false) String viewType,
                                HttpServletRequest request) {

        if (CoinConstants.COIN_PAGE.equals(viewType)) {
            ModelAndView modelAndView = buildView(request, "project/invited");
            FuUserVO user = super.getUser();
            Long userId = user.getId();
            // 邀请到的用户
            Map<String, Object> params = new HashMap<>();
            params.put("dataStatus", 1);
            params.put("shareUserId", userId);
            List<FuUserShareRecordVO> fuUserShareRecordVOS = this.shareRecordService.loadFuUserShareRecord(params);
            if (!fuUserShareRecordVOS.isEmpty()) {
                for (FuUserShareRecordVO fuUserShareRecordVO : fuUserShareRecordVOS) {
                    String username = fuUserShareRecordVO.getUsername();
                    username = username.substring(0, 5) + "*********";
                    fuUserShareRecordVO.setUsername(username);

                    SimpleDateFormat format = new SimpleDateFormat("YYYY-MM-dd");
                    Date createdDate = fuUserShareRecordVO.getCreatedDate();
                    String formatDate = format.format(createdDate);
                    fuUserShareRecordVO.setCreateDateFormate(formatDate);
                }
                modelAndView.addObject("invitedRecordList", fuUserShareRecordVOS);
            }

            String invitation = "https://fo.com/registration?viewType=page&wlink=";
            try {
                DESKeySpec keySpec = new DESKeySpec(CoinConstants.INVITE_SERCET_KEY.getBytes());
                SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("des");
                SecretKey secretKey = keyFactory.generateSecret(keySpec);

                Cipher cipher = Cipher.getInstance("des");
                cipher.init(Cipher.ENCRYPT_MODE, secretKey, new SecureRandom());
                byte[] cipherData = cipher.doFinal(userId.toString().getBytes());
                String sercretUserId = new BASE64Encoder().encode(cipherData);
                invitation = invitation + sercretUserId;
                modelAndView.addObject("inviteUrl" , invitation);
            } catch (InvalidKeyException e) {
                e.printStackTrace();
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (InvalidKeySpecException e) {
                e.printStackTrace();
            } catch (NoSuchPaddingException e) {
                e.printStackTrace();
            } catch (IllegalBlockSizeException e) {
                e.printStackTrace();
            } catch (BadPaddingException e) {
                e.printStackTrace();
            }

            return modelAndView;
        }

        return null;
    }

    /**
     * 资产估值
     *
     * @param fuUserWalletVOS
     * @return
     */
    private Double assetValuation(List<FuUserWalletVO> fuUserWalletVOS) {
        // 资产总估值
        Double totalValuation = 0d;
        Map<String, Object> params = new HashMap<>();

        /***** 调用计算的 BTC 估值的接口 *****/
        // 发起一个币新获取汇率请求，获取返回数据
        Map<String, Double> tickerMap = CoinUserWalletUtils.getTickers();
        if (tickerMap == null) {
            return null;
        }
        /***** 再将所有的估值相加 *****/
        // 用 btc 进行估值
        String coinValuationType = CoinConstants.COIN_VALUATION_TYPE;
        Long coinValuationId = CoinConstants.COIN_VALUATION_ID;
        for (FuUserWalletVO fuUserWalletVO : fuUserWalletVOS) {

            // 用户没有币种对应的钱包
            if (fuUserWalletVO.getCoinId() == null) {
                fuUserWalletVO.setBalance(0d);
                fuUserWalletVO.setAvailable(0d);
                fuUserWalletVO.setValuation(0d);
                continue;
            }

            // 1虚拟币 2代币
            Integer type = fuUserWalletVO.getType();
            // 某种币的数量
            Double balance = fuUserWalletVO.getBalance();
            // 这种币的简称,小写
            String coinName = fuUserWalletVO.getCoinName().toLowerCase();
            Double last = null;
            if (type.equals(CoinConstants.COIN_TYPE_VIRTUAL_COIN)) {
                if (coinName.equals(coinValuationType)) {
                    // 是 btc 不需要转换
                    last = 1d;
                } else {
                    String code = coinName + coinValuationType;
                    last = tickerMap.get(code);
                }
            } else {
                Long coinId = fuUserWalletVO.getCoinId();
                params.clear();
                params.put("tokenId", coinId);
                params.put("coinId", coinValuationId);
                params.put("dataStatus", 1);
                CoinTokenCoinVO coinTokenCoin = this.tokenCoinService.getCoinTokenCoin(params);
                last = coinTokenCoin.getProportion();
            }
            // 可能没有相应汇率
            if (last == null) {
                continue;
            }
            Double valuation = NumberArithmeticUtils.safeMultiply(last, balance).doubleValue();
            fuUserWalletVO.setValuation(valuation);
            totalValuation = NumberArithmeticUtils.safeAdd(totalValuation, valuation);
        }
        return totalValuation;
    }

    @Autowired
    private ICoinTokenCoinService tokenCoinService;
    @Autowired
    private ICoinProjectService projectService;
    @Autowired
    private IFuCapitalRechargeService rechargeService;
    @Autowired
    private IFuCapitalWithdrawService withdrawService;
    @Autowired
    private IFuUserWalletService walletService;
    @Autowired
    private IFuUserService userService;
    @Autowired
    private IFuUserShareRecordService shareRecordService;
}
